package com.franklin.java.api.psi.data.resolver;

import com.franklin.java.api.psi.data.PsiData;
import com.franklin.java.utils.PsiUtils;
import com.intellij.psi.*;
import com.intellij.psi.util.PsiTreeUtil;

import java.util.Objects;

/**
 * @author Franklin
 * @since 2021/08/15/ 21:34
 */
public class MethodReferenceResolver implements PsiDataResolver{

    @Override
    public PsiData resolve(String name, String value, PsiElement dataElement) {
        PsiElement psiElement = null;
        String val = value;
        String type = "String";
        String typeFullName = "java.lang.String";
        PsiCodeBlock psiCodeBlock = PsiTreeUtil.getParentOfType(dataElement, PsiCodeBlock.class);
        if (Objects.isNull(psiCodeBlock)){
            return null;
        }
        String psiCodeBlockText = psiCodeBlock.getText();
        String[] lines = psiCodeBlockText.split("\n");
        int length = 0;
        PsiElement psiReference = null;
        for (String line : lines) {
            if (line.trim().startsWith("/")){
                length = length + line.length() + 1;
                continue;
            }
            int valueIndex = line.indexOf(value);
            if (valueIndex >= 0) {
                psiReference = psiCodeBlock.findElementAt(length + valueIndex);
                if (Objects.nonNull(psiReference)){
                    break;
                }
            }
            length = length + line.length() + 1;
        }
        if (Objects.isNull(psiReference)){
            return null;
        }

        PsiMethodCallExpression psiMethodCallExpression = PsiUtils.findFullMethodCallExpression(psiReference,value);

        if (Objects.isNull(psiMethodCallExpression)){
            return null;
        }

        PsiType psiType = psiMethodCallExpression.getType();
        if (Objects.nonNull(psiType)) {
            typeFullName = PsiUtils.findTypeFullName((PsiJavaFile) dataElement.getContainingFile(), psiType.getPresentableText());
            psiElement = psiMethodCallExpression;
            return new PsiData(type,val,psiElement,typeFullName, dataElement);
        }
        return null;
    }
}
